from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework import status
from courses.models import Course, CourseExpire
from django_redis import get_redis_connection
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from django.conf import settings

import logging
log = logging.getLogger('django')

class CartAPIView(ViewSet):

    # 判断用户是否登录
    # permission_classes = [IsAuthenticated,]

    @action(methods=['GET'], detail=False)
    def get_total(self, request):
        '''每次用户登录就获取对应的购物车数量'''
        user_id = request.user.id
        redis = get_redis_connection('cart')

        # 获取购物车中商品的总数
        total = redis.hlen('cart_%s' % user_id)
        return Response({'message': '成功获取数量','total': total}, status=status.HTTP_200_OK)

    @action(methods=['POST'], detail=False)
    def add_course(self, request):
        '''添加商品到购物车'''
        # 获取用户id，商品id，商品有效期和购物车商品勾选状态
        user_id = request.user.id
        course_id = request.data.get('course_id')
        expire = 0  # 默认为0，0表示永久有效
        is_select = True    # 勾选状态

        # 查找和验证数据
        try:
            course = Course.objects.get(is_delete=False, is_show=True, pk=course_id)
        except:
            return Response({'message': '对不起，您购买的商品不存在'},status=status.HTTP_400_BAD_REQUEST)

        # 添加数据到购物车中
        try:
            redis = get_redis_connection('cart')
            pip = redis.pipeline()
            pip.multi()

            # 保存商品信息到购物车中
            pip.hset('cart_%s' % user_id, course_id, expire)
            # 保存购物车中商品的勾选状态
            pip.sadd('selected_%s' % user_id, course_id)
            # 执行管道中的命令
            pip.execute()

            # 获取购物车中商品的总数
            total = redis.hlen('cart_%s' % user_id)
        except:
            log.error("购物车商品添加失败，redis操作出错！")
            return Response({'message': '商品添加失败，请联系工作人员'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

        return Response({'message': '商品添加成功', 'total': total}, status=status.HTTP_201_CREATED)

    @action(methods=['GET'], detail=False)
    def get(self,request):
        '''购物车商品列表'''
        user_id = request.user.id
        redis = get_redis_connection('cart')

        # 从hash里面读取购物车基本信息
        cart_course_list = redis.hgetall('cart_%s' % user_id)
        # 从set集合中查询所有已经勾选的商品ID
        cart_selected_list = redis.smembers('selected_%s' % user_id)

        data = []

        # 如果提取到的商品购物车信息为空！，则直接返回空列表
        if len(cart_course_list) < 1:
            return Response(data)

        # 购物车有数据我们就要组装商品课程新返回给客户端
        for course_bytes, expire_bytes in cart_course_list.items():
            # 给课程id解码
            course_id = course_bytes.decode()
            try:
                course = Course.objects.get(pk=course_id)
            except Course.DoesNotExist:
                # 如果没有数据
                pass

            data.append({
                'id': course_id,
                'name': course.name,
                # 这边course.course_img获取到的是个对象，一定要 .url 来获取到url字符串，否则无法序列化
                'course_img': settings.DOMAIL_IMAGE_URL + course.course_img.url,
                'price': course.real_price(),
                'is_selected': True if course_bytes in cart_selected_list else False,
                'expire_list': course.expire_list,
            })

        return Response(data)

    @action(methods=['patch'], detail=False)
    def patch(self,request):
        '''切换购物车中的商品勾选状态'''
        user_id = request.user.id
        course_id = request.data.get('course_id')
        is_selected = bool(request.data.get('is_selected'))

        # 校验商品是否存在
        try:
            course = Course.objects.get(pk=course_id, is_show=True, is_delete=False)
        except:
            return Response({'message': '对不起，您选择的商品不存在'}, status=status.HTTP_400_BAD_REQUEST)

        # 更新购物车中的商品
        try:
            redis = get_redis_connection('cart')
            if is_selected:
                # 如果勾选，则将商品添加到勾选商品的redis库中
                redis.sadd('selected_%s' % user_id, course_id)
            else:
                # 如果不勾选，则将商品从勾选商品的redis库中删除
                redis.srem('selected_%s' % user_id, course_id)
        except:
            return Response({'message': '购物车勾选操作有误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({'message': '切换勾选状态成功'}, status=status.HTTP_200_OK)

    @action(methods=['put'], detail=False)
    def put(self,request):
        '''切换购物车的课程的有效期，保存到redis中'''
        # 需要user_id, course_id, 有效期选项, 这三个值
        user_id = request.user.id
        course_id = request.data.get('course_id')
        expire = request.data.get('expire')
        redis = get_redis_connection('cart')
        redis.hset('cart_%s' % user_id, course_id, expire)
        return Response({'message': '调整有效期成功'})


    @action(methods=['delete'], detail=False)
    def delete(self,request):
        '''删除购物车中的商品'''
        user_id = request.user.id
        print(user_id)
        # 因为请求方式中的get和delete是没有请求体的，所以去数据要使用params进行传参
        course_id = request.query_params.get("course_id")
        print(course_id)

        try:
            course = Course.objects.get(is_delete=False, is_show=True, pk=course_id)
        except:
            return Response({'message': '对不起，您选择的商品不存在'}, status=status.HTTP_400_BAD_REQUEST)

        redis = get_redis_connection("cart")
        pip = redis.pipeline()
        pip.multi()
        pip.hdel("cart_%s" % user_id, course_id)
        pip.srem("selected_%s" % user_id, course_id)
        pip.execute()

        return Response({'message': '删除商品成功'},status=status.HTTP_200_OK)

    @action(methods=['get'], detail=False)
    def selected(self,request):
        '''获取勾选的商品课程列表'''
        user_id = request.user.id
        redis = get_redis_connection('cart')
        cart_list = redis.hgetall('cart_%s' % user_id)
        selected_set = redis.smembers('selected_%s' % user_id)

        data = []
        for course_id_byte in selected_set:
            course_id = course_id_byte.decode()
            try:
                course = Course.objects.get(is_show=True, is_delete=False, pk=course_id)
            except Course.DoesNotExist:
                return Response({'message': '对不起，您选择的商品不存在'},status=status.HTTP_400_BAD_REQUEST)

            try:
                course_expire = CourseExpire.objects.get(is_show=True, is_delete=False, course=course, expire_time=cart_list.get(course_id_byte))
                expire_text = course_expire.expire_text
                price = course_expire.price
            except CourseExpire.DoesNotExist:
                expire_text = "永久有效"
                price = course.price

            data.append({
                'id': course_id,
                'name': course.name,
                'course_img': settings.DOMAIL_IMAGE_URL + course.course_img.url,
                'expire': expire_text,
                'real_price': course.real_price(price),
                'price': price,
                'discount_name': course.discount_name,
            })


        return Response(data)








